/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ebookmgr;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;

/**
 *
 * // set file hidden.
 * File arquivo = new File("Example.txt");
 * arquivo.createNewFile();
 * String comando = "C:\\WINDOWS\\System32\\ATTRIB.EXE +H Example.txt";
 *
 * Runtime.getRuntime().exec(comando );
 *
 *
 * @author mazhao
 */
public class Configuration {



    // =================
    // System Property
    // =================
    public static final String LINE_SEP = System.getProperty("line.separator");
    public static final String FILE_SEP = System.getProperty("file.separator");
    public static final String USER_HOME = System.getProperty("user.home");


    // ============================
    // Application Name and Version
    // ============================
    // Application Name for Windows
    public static final String APP_NAME_WIN = "ebookmgr";
    // Application Name for Mac
    public static final String APP_NAME_MAC = ".ebookmgr";
    // Application Name for Linux
    public static final String APP_NAME_LINUX = ".ebookmgr";

    // Application Version
    public static final String VERSION = "1.0";


    // ============================
    // Configuration File Name
    // ============================
    // folder tree configuration file name
    public static final String CONF_FILE_NAME = "configure";
    // folder location configuration file name
    public static final String BOOK_FOLDER_FILE_NAME = "bookfolder";
    // book file extension file
    public static final String FILE_EXTENSION_FILE_NAME = "extension";
    // book file extension separated by comma
    public static final String FILE_EXTENSION_SEP = ",";

    // database sub folder in user.home
    public static final String DB_SUB_FOLDER = "datastore";
    // database name in databse sub folder
    public static final String DB_NAME = "ebm";

    public static final String DB_FILE_NAME = "ebm.script";

    // ========================================================
    // Configuration File Init Content
    // ========================================================
    // default folder tree configuration
    public static final String CONF_FILE_CONT =
            "Compoter Books:*"                                  + LINE_SEP +
            "    OS:*"                                          + LINE_SEP +
            "        Linux:linux,fecora core,ubuntu"            + LINE_SEP +
            "    Programming Language:*"                        + LINE_SEP +
            "        Java:java,swing,awt,Hibernate"             + LINE_SEP +
            "        C,C++:c,c++,gcc,vc,bc"                     + LINE_SEP +
            "    Management:*"                                  + LINE_SEP +
            "        PMP:PMP, Project Management Professional"  + LINE_SEP;

    // default value for extension file.
    public static final String FILE_EXTENSION_CONT =
            ".pdf,.chm,.doc,.docx" + LINE_SEP +
            ".pdf,.chm,.doc";

    // ============================
    // Default IO Buffer Size.
    // ============================
    // Default Buffer Size for writing configuration file.
    // see http://www.xiguaforever.net/confluence/display/JPT/Java+File+IO+Analysis#JavaFileIOAnalysis-Regularjavaiostreambuffer
    public static final int BUFFER_SIZE = 32 * 1024;

    // ====================================================================================
    // Application Home Folder and Congifuration File Absolute Path
    // ====================================================================================
    private static final String CONF_FOLDER_PATH = USER_HOME + FILE_SEP + "{appname}" + FILE_SEP + VERSION;
    private static final String CONF_FILE_PATH = CONF_FOLDER_PATH + FILE_SEP + CONF_FILE_NAME;
    private static final String BOOK_FOLDER_FILE_PATH = CONF_FOLDER_PATH + FILE_SEP + BOOK_FOLDER_FILE_NAME;
    private static final String FILE_EXTENSION_FILE_PATH = CONF_FOLDER_PATH + FILE_SEP + FILE_EXTENSION_FILE_NAME;

    public static final String DATASTORE_PATH = CONF_FOLDER_PATH + FILE_SEP + DB_SUB_FOLDER + FILE_SEP + DB_NAME;
    public static final String DATABASE_FILE_PATH =CONF_FOLDER_PATH + FILE_SEP + DB_SUB_FOLDER  + FILE_SEP + DB_FILE_NAME;

    //
    //
    //
    public static final String STAR_MAC = "";
    public static final String STAR_WIN = "★";
    public static final String STAR_LINUX = "★";

    /**
     * replace {appname} with ebookmrg(win) or .ebookmgr(*uix)
     * @param org
     * @return
     */
    private static String replaceAppName(String org) {
        String value = null;

        if (EBookMgrUtil.isWindows()) {
            value = org.replace("{appname}", APP_NAME_WIN);
        } else if (EBookMgrUtil.isMac()) {
            value = org.replace("{appname}", APP_NAME_MAC);
        } else if (EBookMgrUtil.isLinux()) {
            value = org.replace("{appname}", APP_NAME_LINUX);
        } else {
            value = org.replace("{appname}", APP_NAME_LINUX);
        }

        return value;
    }



    /**
     *
     * @param path configuration file absolute path
     * @param initValue init value for empty file
     * @param line from 1 to max
     * @return
     */
    private static String getStringFromFile(String path, String initValue, int line) {
        String retValue = null;

        // 1. replace appname
        path = replaceAppName(path);
        initValue = replaceAppName(initValue);
        

        // 2. check parent folder exist.

        File thisFile = new File(path);
        File parentFile = thisFile.getParentFile();

        if(!parentFile.exists()) {
            if(!parentFile.mkdirs()){
                EBookMgrUtil.showMessageAndExit("Can not make configuration folder:" + parentFile.getAbsolutePath());
            }
        }

        // 3. check configuration file exist, if not exist create and write initValue, else read specific line and return
        if(!thisFile.exists()){
            BufferedWriter bw = null;
            try {
                bw = new BufferedWriter(new FileWriter(thisFile));
                bw.write(initValue);
            } catch (IOException ex) {
                EBookMgrUtil.showMessageAndExit("Can not write init value to:" + thisFile.getAbsolutePath());
            } finally {
                EBookMgrUtil.safelyClose(bw);
            }
        }

        // 4. read value in file

        BufferedReader  br = null;
        try {
            br = new BufferedReader(new FileReader(thisFile));

            // line from 1 to max
            for(int i = 1; i < line; i++) {
                br.readLine();
            }

            retValue = br.readLine();

        } catch (IOException ex) {
            EBookMgrUtil.showMessageAndExit("Can not read value from:" + thisFile.getAbsolutePath());
        } finally {
            EBookMgrUtil.safelyClose(br);
        }


        return retValue;
    }


    /**
     *
     * @param path save file path
     * @param content line content
     * @param line line to be replace, from 1 to max
     */
    private static void saveStringToFile(String path, String content, int line) {

        BufferedReader br = null;
        BufferedWriter bw = null;
        List<String> fileContent = new ArrayList<String>();

        path = replaceAppName(path);

        // 1. read file content
        try {
            br = new BufferedReader(new FileReader(path));

            String curLine = null;

            while( (curLine = br.readLine()) != null) {
                fileContent.add(curLine);
            }
        } catch (IOException ex) {
            EBookMgrUtil.showMessageAndExit("can not read file from :" + path);
        } finally {
            EBookMgrUtil.safelyClose(br);
        }

        // replace the line
        fileContent.set(line - 1, content);

        // save to file again
        try {
            bw = new BufferedWriter(new FileWriter(path));
            for(String curLine : fileContent) {
                bw.write(curLine);
                bw.write(LINE_SEP);
            }
        } catch (IOException ex) {
            EBookMgrUtil.showMessageAndExit("can not save file to:" + path);
        } finally {
            EBookMgrUtil.safelyClose(bw);
        }

    }


    public static String getConfFilePath() {
        String file = replaceAppName(CONF_FILE_PATH);


        BufferedWriter br = null;

        try {

            // if folder not exist, create it
            File thisFile = new File(file);

            File parentFile = thisFile.getParentFile();
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }

            // if file not exist, write default content.
            if (!thisFile.exists()) {
                br = new BufferedWriter(new FileWriter(thisFile));
                br.write(CONF_FILE_CONT);
            }

        } catch (Exception ex) {
            EBookMgrUtil.showMessageAndExit(ex.getMessage());
        } finally {
            EBookMgrUtil.safelyClose(br);
        }

        return file;
    }

    public static String getBaseFolderPath() {
        return getStringFromFile(Configuration.BOOK_FOLDER_FILE_PATH, CONF_FOLDER_PATH, 1);
    }

    

    public static final List<String> getAllFileExtension() {

        String line = getStringFromFile(Configuration.FILE_EXTENSION_FILE_PATH, FILE_EXTENSION_CONT, 1);
        String[] exts = line.split(FILE_EXTENSION_SEP);
        List<String> ret = Arrays.asList(exts);

        return ret;
    }

    public static final List<String> getSelectedFileExtension() {

        String line = getStringFromFile(Configuration.FILE_EXTENSION_FILE_PATH, FILE_EXTENSION_CONT, 2);
        String[] exts = line.split(FILE_EXTENSION_SEP);
        List<String> ret = Arrays.asList(exts);

        return ret;
    }


    public static void saveBaseFolderPath(String path) {
        saveStringToFile(BOOK_FOLDER_FILE_PATH, path, 1);
    }

    public static void saveSelectedFileExtension(List<String> exts) {
        StringBuilder sb = new StringBuilder();
        for(String s : exts) {
            sb.append(s).append(FILE_EXTENSION_SEP);
        }
        sb.deleteCharAt(sb.length() - 1);
        Configuration.saveStringToFile(FILE_EXTENSION_FILE_PATH, sb.toString(), 2);
        
    }

    public static String getUIString(String key) {
        
       ResourceBundle res = ResourceBundle.getBundle("ebookmgr.resources.ui", Locale.getDefault());
       String value = res.getString(key);

        return value;
    }

    public static String getDatabasePath() {
        return replaceAppName(Configuration.DATASTORE_PATH);
    }

    public static String getDatabaseFilePath() {
        return replaceAppName(DATABASE_FILE_PATH);
    }

    public static String getStar() {
        String value = "";
        if (EBookMgrUtil.isWindows()) {
            value = STAR_WIN;
        } else if (EBookMgrUtil.isMac()) {
            value = STAR_MAC;
        } else if (EBookMgrUtil.isLinux()) {
            value = STAR_LINUX;
        } else {
            value = STAR_LINUX;
        }

        return value;

    }
}
